classdef GetWorkingPoint < Table1.NMRGJobs.NMRGJob
    methods
        function obj = GetWorkingPoint(nmrg)
            obj@Table1.NMRGJobs.NMRGJob(nmrg, 'GetWorkingPoint');
            obj.defineParameter();
        end
        
        function obj = defineParameter(obj)
            obj.paramParser=inputParser;
            obj.paramParser.addParameter('frequencyZ', 100e3, @(x) x>0);
            obj.paramParser.addParameter('amplitudeZ', 3.0, @(x) x>0 && x<5);
            obj.paramParser.addParameter('frequencyTrans', 20, @(x) x>0);
            obj.paramParser.addParameter('amplitudeTransX', 0.01, @(x) x>0 && x<1);
            obj.paramParser.addParameter('amplitudeTransY', 0.05, @(x) x>0 && x<1);
            obj.paramParser.addParameter('nPoint', 30, @(x) x>=10 && x<=100);
            obj.paramParser.addParameter('nAverage', 10, @(x) x>=1 && x<=100);
            obj.paramParser.addParameter('initialBx0', 0.0, @(x) x>= -3.0 && x <= 3.0);
            obj.paramParser.addParameter('initialBy0', 0.0, @(x) x>= -3.0 && x <= 3.0);
            obj.paramParser.addParameter('quadrantX', 0, @(x) ismember(x, [0, 1]) );
            obj.paramParser.addParameter('quadrantY', 1, @(x) ismember(x, [0, 1]) );
            obj.paramParser.addParameter('transDCscale', 1000, @(x) x>0);
            obj.paramParser.addParameter('transACscale', 100, @(x) x>0);
            obj.paramParser.addParameter('isReport', false, @islogical);
            obj.paramParser.addParameter('isPlot', true, @islogical);
            obj.paramParser.addParameter('description', 'No description.', @ischar);
        end
        
        %%
        function obj = preprocess(obj)
            param = obj.dataPackage.parameters;
            
            obj.boss.setParametricMagnetometer('frequencyZ', param.frequencyZ, ...
                'amplitudeZ', param.amplitudeZ, ...
                'initialBx0', param.initialBx0, ...
                'initialBy0', param.initialBy0, ...
                'bandwidthAC', 5.0*param.frequencyTrans, ...
                'transDCscale', 0, ...
                'transACscale', param.transACscale);
            
            obj.boss.UnlockTransverseField(); pause(0.5);
        end
        
        %%
        % function dataAcquisition() defined in an independent file.
        
        %%
        function obj = analyze(obj)
            measuredData = obj.dataPackage.measurement_data;
            
            analysis_result.phaseX = measuredData.FinePhaseXFitting.phase0;
            analysis_result.phaseY = measuredData.FinePhaseYFitting.phase0;
            analysis_result.biasX = measuredData.BiasXFitting.zeropoint;
            analysis_result.biasY = measuredData.BiasYFitting.zeropoint;
            analysis_result.slopeX = measuredData.BiasXFitting.slope;
            analysis_result.slopeY = measuredData.BiasYFitting.slope;
            
            obj.dataPackage.analysis_result = analysis_result;
        end
        
        %%
        function obj = postprocess(obj)
            param = obj.dataPackage.parameters;
            measuredData = obj.dataPackage.measurement_data;
            analysis = obj.dataPackage.analysis_result;
            
            %% Post operations
            % do nothing
            
            %% summary
            summary.start = datestr(measuredData.start);
            summary.mainFrequency = param.frequencyZ;
            summary.phaseX = analysis.phaseX;
            summary.phaseY = analysis.phaseY;
            summary.biasX = analysis.biasX;
            summary.biasY = analysis.biasY;
            summary.slopeX = analysis.slopeX;
            summary.slopeY = analysis.slopeY;
            summary.exportScaleDC = param.transDCscale;
            summary.exportScaleAC = param.transACscale;
            summary.finish = datestr(measuredData.finish);
            
            obj.dataPackage.summary = summary;
            obj.boss.SystemInfo.WorkingPoint = summary;
            
            % Store Data
            getSession;
            sess.addData('GetWorkingPoint', obj.dataPackage, param.description);
        end

        %%
        % function presentation() defined in an independent file.

    end
    %%
    methods(Static)
        function res = compare(objList, varargin)
            p = inputParser;
            p.addParameter('isPlot', true, @islogical);
            p.addParameter('viewer', [], @(x)  isa(x, 'Table1.GUI.DataViewer') || isempty(x));
            p.parse(varargin{:});
            
            res = compare@Table1.NMRGJobs.NMRGJob(objList, 'viewer', p.Results.viewer);

            if p.Results.isPlot
                if isempty(p.Results.viewer)
                    f = figure('Name', 'WorkingPoint');
                    ax1 = subplot(3, 2, 1, 'Parent', f);
                    ax2 = subplot(3, 2, 2, 'Parent', f);
                    ax3 = subplot(3, 2, 3, 'Parent', f);
                    ax4 = subplot(3, 2, 4, 'Parent', f);
                    ax5 = subplot(3, 2, 5, 'Parent', f);
                    ax6 = subplot(3, 2, 6, 'Parent', f);
                else
                    ax1 = subplot(3, 2, 1, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                    ax2 = subplot(3, 2, 2, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                    ax3 = subplot(3, 2, 3, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                    ax4 = subplot(3, 2, 4, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                    ax5 = subplot(3, 2, 5, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                    ax6 = subplot(3, 2, 6, 'Parent', p.Results.viewer.gui.uiHandle.panelPlot);
                end
                rawPhaseX = arrayfun(@(d) d.RawPhaseXData.getNodeData(1), res.measuredData);
                rawPhaseY = arrayfun(@(d) d.RawPhaseYData.getNodeData(1), res.measuredData);
                finePhaseX = arrayfun(@(d) d.FinePhaseXData.getNodeData(1), res.measuredData);
                finePhaseY = arrayfun(@(d) d.FinePhaseYData.getNodeData(1), res.measuredData);
                biasPhaseX1 = arrayfun(@(d) d.BiasXData.getNodeData(1), res.measuredData);
                biasPhaseX2 = arrayfun(@(d) d.BiasXData.getNodeData(2), res.measuredData);
                biasPhaseY1 = arrayfun(@(d) d.BiasYData.getNodeData(1), res.measuredData);
                biasPhaseY2 = arrayfun(@(d) d.BiasYData.getNodeData(2), res.measuredData);
                
                nlen = length(res.measuredData);
                plot(ax1, reshape([rawPhaseX.x], [], nlen), reshape([rawPhaseX.y], [], nlen), '.-'); grid(ax1, 'on'); xlabel(ax1, 'PhaseX (degree)'); ylabel(ax1, 'Demod Signal (V)');
                plot(ax2, reshape([rawPhaseY.x], [], nlen), reshape([rawPhaseY.y], [], nlen), '.-'); grid(ax2, 'on'); xlabel(ax2, 'PhaseY (degree)'); ylabel(ax2, 'Demod Signal (V)');
                plot(ax3, reshape([finePhaseX.x], [], nlen), reshape([finePhaseX.y], [], nlen), '.-'); grid(ax3, 'on'); xlabel(ax3, 'PhaseX (degree)'); ylabel(ax3, 'Demod Signal (V)');
                plot(ax4, reshape([finePhaseY.x], [], nlen), reshape([finePhaseY.y], [], nlen), '.-'); grid(ax4, 'on'); xlabel(ax4, 'PhaseY (degree)'); ylabel(ax4, 'Demod Signal (V)');
                plot(ax5, reshape([biasPhaseX1.x], [], nlen), reshape([biasPhaseX1.y], [], nlen), '.-', reshape([biasPhaseX2.x], [], nlen), reshape([biasPhaseX2.y], [], nlen), '.-'); grid(ax5, 'on');grid(ax1, 'on'); xlabel(ax5, 'BiasX (V)'); ylabel(ax5, 'Demod Signal (V)');
                plot(ax6, reshape([biasPhaseY1.x], [], nlen), reshape([biasPhaseY1.y], [], nlen), '.-', reshape([biasPhaseY2.x], [], nlen), reshape([biasPhaseY2.y], [], nlen), '.-'); grid(ax6, 'on');grid(ax1, 'on'); xlabel(ax6, 'BiasY (V)'); ylabel(ax6, 'Demod Signal (V)');

            end
        end
    end
end

